package org.hentai.tri.grpc.cilent;

import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.stream.StreamObserver;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.hentai.tri.grpc.Hentai;
import org.hentai.tri.grpc.HentaiReply;
import org.hentai.tri.grpc.HentaiRequest;

import java.io.IOException;

public class HentaiTriOpClient {

    private final Hentai hentai;

    public HentaiTriOpClient(int port) throws IOException {
        DubboBootstrap bootstrap = DubboBootstrap.getInstance();
        ReferenceConfig<Hentai> ref = new ReferenceConfig<>();
        ref.setInterface(Hentai.class);
        ref.setProtocol(CommonConstants.TRIPLE);
        ref.setProxy(CommonConstants.NATIVE_STUB);
        ref.setTimeout(5000);
        ref.setUrl(String.format("tri://localhost:%d", port));

        bootstrap.application(new ApplicationConfig("tri-stub-consumer"))
                .reference(ref)
                .start();

        System.out.println("HentaiTriOpClient started at port " + port);

        hentai = ref.get();

        unary();
        biStream();
        serverStream();

        System.in.read();

    }

    public static void main(String[] args) throws IOException {
        new HentaiTriOpClient(50051);
    }

    private void unary() {
        System.out.println("start unary");
        HentaiReply reply = hentai.hentai(HentaiRequest.newBuilder()
                .setName("[tripe client] lolicon")
                .build());
        System.out.println("unary reply: " + reply);
    }

    private void biStream() {
        StreamObserver<HentaiRequest> requestStreamObserver = hentai.biStream(new SampleStreamObserver());
        for (int i = 0; i < 10; i++) {
            HentaiRequest request = HentaiRequest.newBuilder()
                    .setName("[tripe client] lolicon")
                    .build();
            requestStreamObserver.onNext(request);
        }
        requestStreamObserver.onCompleted();
    }

    private void serverStream() {
        HentaiRequest request = HentaiRequest.newBuilder()
                .setName("[tripe client] lolicon")
                .build();
        hentai.serverSteam(request, new SampleStreamObserver());
    }

    private static class SampleStreamObserver implements StreamObserver<HentaiReply> {

        @Override
        public void onNext(HentaiReply data) {
            System.out.printf("stream <- reply: %s\n", data);
        }

        @Override
        public void onError(Throwable throwable) {
            System.err.printf("stream <- reply: %s\n", throwable);
            throwable.printStackTrace();
        }

        @Override
        public void onCompleted() {
            System.out.println("stream completed");
        }
    }

}
